<template>
  <div 
    v-if="visible"
    ref="animElement"
    class="fixed z-50 w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white font-bold pointer-events-none"
    :style="{
      left: position.x + 'px',
      top: position.y + 'px',
      transform: 'translate(-50%, -50%)',
      opacity: opacity,
      scale: scale
    }"
    style="transition: all 0.1s linear;"
  >
    +1
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick, watch } from 'vue';

const props = defineProps<{
  startPos: { x: number; y: number };
  endPos: { x: number; y: number };
}>();

const animElement = ref<HTMLElement | null>(null);
const visible = ref(false);
const position = ref({ x: 0, y: 0 });
const opacity = ref(1);
const scale = ref(1);
let animationId: number | null = null;

const startAnimation = () => {
  visible.value = true;
  position.value = { ...props.startPos };
  
  // 确保DOM已更新
  nextTick(() => {
    if (!animElement.value) return;
    
    const startTime = performance.now();
    const duration = 800; // 动画总时长
    
    const animate = (currentTime: number) => {
      if (!animElement.value) return;
      
      const elapsed = currentTime - startTime;
      const progress = Math.min(elapsed / duration, 1);
      
      // 抛物线运动公式
      const controlPoint = {
        x: props.startPos.x - (props.startPos.x - props.endPos.x) * 0.3,
        y: props.startPos.y - 150
      };
      
      position.value.x = 
        Math.pow(1 - progress, 2) * props.startPos.x + 
        2 * (1 - progress) * progress * controlPoint.x + 
        Math.pow(progress, 2) * props.endPos.x;
        
      position.value.y = 
        Math.pow(1 - progress, 2) * props.startPos.y + 
        2 * (1 - progress) * progress * controlPoint.y + 
        Math.pow(progress, 2) * props.endPos.y;
      
      // 动画结束时效果
      if (progress > 0.8) {
        const endProgress = (progress - 0.8) / 0.2;
        scale.value = 1 - endProgress * 0.5;
        opacity.value = 1 - endProgress;
      }
      
      // 继续动画或结束
      if (progress < 1) {
        animationId = requestAnimationFrame(animate);
      } else {
        visible.value = false;
      }
    };
    
    // 开始动画
    animationId = requestAnimationFrame(animate);
  });
};

// 当props变化时重新开始动画
watch(() => props.startPos, startAnimation, { immediate: true });

// 组件卸载时取消动画
onMounted(() => {
  return () => {
    if (animationId) {
      cancelAnimationFrame(animationId);
    }
  };
});
</script>